package com.thiswhyme.storage.config;

import com.aliyun.oss.OSS;
import com.baidubce.services.bos.BosClient;
import com.obs.services.ObsClient;
import com.qcloud.cos.auth.COSCredentials;
import com.qiniu.util.Auth;
import com.thiswhyme.common.expection.BusinessException;
import com.thiswhyme.storage.core.FileStorage;
import com.thiswhyme.storage.core.FileStorageService;
import com.thiswhyme.storage.core.platform.*;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @description: 对象存储配置
 * @author: thiswhyme
 * @date: 2021/6/29
 */
@Configuration
@EnableConfigurationProperties(StorageProperties.class)
public class StorageAutoConfiguration {

    @Bean
    @ConditionalOnClass(OSS.class)
    public List<FileStorage> aliyunOssService(StorageProperties storageProperties) {
        Map<String, StorageProperties.OssProperty> propertyMap = storageProperties.getOss();
        if (CollectionUtils.isEmpty(propertyMap)) {
            return null;
        }
        return propertyMap.entrySet().stream().map(propertyEntry -> {
            String configKey = propertyEntry.getKey();
            StorageProperties.OssProperty property = propertyEntry.getValue();
            if (!StringUtils.hasText(configKey) || null == property) {
                throw new BusinessException("阿里云OSS配置不完整");
            }
            return new AliyunOssStorage(configKey, property.getEndpoint(), property.getAccessKey(),
                    property.getSecretKey(), property.getBucketName(), property.getDomain());
        }).collect(Collectors.toList());
    }

    @Bean
    @ConditionalOnClass(Auth.class)
    public List<FileStorage> qiniuKodoService(StorageProperties storageProperties) {
        Map<String, StorageProperties.KodoProperty> propertyMap = storageProperties.getKodo();
        if (CollectionUtils.isEmpty(propertyMap)) {
            return null;
        }
        return propertyMap.entrySet().stream().map(propertyEntry -> {
            String configKey = propertyEntry.getKey();
            StorageProperties.KodoProperty property = propertyEntry.getValue();
            if (!StringUtils.hasText(configKey) || null == property) {
                throw new BusinessException("七牛云KODO配置不完整");
            }
            return new QiniuKodoStorage(configKey, property.getAccessKey(), property.getSecretKey(),
                    property.getBucketName(), property.getDomain());
        }).collect(Collectors.toList());
    }

    @Bean
    @ConditionalOnClass(COSCredentials.class)
    public List<FileStorage> tencentCosService(StorageProperties storageProperties) {
        Map<String, StorageProperties.CosProperty> propertyMap = storageProperties.getCos();
        if (CollectionUtils.isEmpty(propertyMap)) {
            return null;
        }
        return propertyMap.entrySet().stream().map(propertyEntry -> {
            String configKey = propertyEntry.getKey();
            StorageProperties.CosProperty property = propertyEntry.getValue();
            if (!StringUtils.hasText(configKey) || null == property) {
                throw new BusinessException("腾讯云COS配置不完整");
            }
            return new TencentCosStorage(configKey, property.getRegion(), property.getSecretId(),
                    property.getSecretKey(), property.getBucketName(), property.getDomain());
        }).collect(Collectors.toList());
    }

    @Bean
    @ConditionalOnClass(ObsClient.class)
    public List<FileStorage> haweiObsService(StorageProperties storageProperties) {
        Map<String, StorageProperties.ObsProperty> propertyMap = storageProperties.getObs();
        if (CollectionUtils.isEmpty(propertyMap)) {
            return null;
        }
        return propertyMap.entrySet().stream().map(propertyEntry -> {
            String configKey = propertyEntry.getKey();
            StorageProperties.ObsProperty property = propertyEntry.getValue();
            if (!StringUtils.hasText(configKey) || null == property) {
                throw new BusinessException("华为云OBS配置不完整");
            }
            return new HaweiObsStorage(configKey, property.getEndpoint(), property.getAccessKey(),
                    property.getSecretKey(), property.getBucketName(), property.getDomain());
        }).collect(Collectors.toList());
    }

    @Bean
    @ConditionalOnClass(BosClient.class)
    public List<FileStorage> baiduBosService(StorageProperties storageProperties) {
        Map<String, StorageProperties.BosProperty> propertyMap = storageProperties.getBos();
        if (CollectionUtils.isEmpty(propertyMap)) {
            return null;
        }
        return propertyMap.entrySet().stream().map(propertyEntry -> {
            String configKey = propertyEntry.getKey();
            StorageProperties.BosProperty property = propertyEntry.getValue();
            if (!StringUtils.hasText(configKey) || null == property) {
                throw new BusinessException("百度云BOS配置不完整");
            }
            return new BaiduBosStorage(configKey, property.getEndpoint(), property.getAccessKey(),
                    property.getSecretKey(), property.getBucketName(), property.getDomain());
        }).collect(Collectors.toList());
    }

    @Bean
    public FileStorageService fileStorageService(List<List<? extends FileStorage>> fileStorageLists) {
        Map<String, FileStorage> fileStorageMap = new HashMap<>(8);
        fileStorageLists.stream().filter(fileStorages -> !CollectionUtils.isEmpty(fileStorages))
                .forEach(fileStorages -> fileStorages
                        .forEach(fileStorage -> {
                            fileStorageMap.put(fileStorage.platformCode(), fileStorage);
        }));
        return new FileStorageService(fileStorageMap);
    }
}
